module Compress_Func (
    input [5:0] index_j_in,//0~63
    input [31:0] A_in,
    input [31:0] B_in,
    input [31:0] C_in,
    input [31:0] D_in,
    input [31:0] E_in,
    input [31:0] F_in,
    input [31:0] G_in,
    input [31:0] H_in,
    input [31:0] Wj_in,
    input [31:0] Wj_p_in,

    output [31:0] A_out,
    output [31:0] B_out,
    output [31:0] C_out,
    output [31:0] D_out,
    output [31:0] E_out,
    output [31:0] F_out,
    output [31:0] G_out,
    output [31:0] H_out
);

wire [31:0] temp_SS1, SS1;
wire [31:0] SS2 ;
wire [31:0] TT1 ;
wire [31:0] TT2 ;
wire [31:0] FF;
wire [31:0] FF_0;
wire [31:0] FF_1;
wire [31:0] GG ;
wire [31:0] GG_0;
wire [31:0] GG_1;
wire [31:0] Tj;
wire [31:0] Tj_shift;
wire [31:0] P0;



//Tj
assign Tj = (index_j_in<16)? 32'h79cc4519 : 32'h7a879d8a;

//SS1 = ((A<<<12) + E + (Tj<<<j)) <<< 7
assign temp_SS1 = {A_in[19:0],A_in[31:20]} + E_in + (Tj_shift);
assign SS1 = {temp_SS1[24:0],temp_SS1[31:25]};

//SS2 = SS1 ^ (A<<<12)
assign SS2 = SS1 ^ {A_in[19:0],A_in[31:20]};

//TT1 = FFj(A,B,C) + D + SS2 + Wj'
assign FF_0 = A_in ^ B_in ^ C_in;
assign FF_1 = (A_in&B_in) | (A_in&C_in) | (B_in&C_in);
assign FF = (index_j_in<16)? FF_0 : FF_1;
assign TT1 = FF + D_in + SS2 + Wj_p_in;

//TT2 = GGj(E,F,G) + H + SS1 + Wj
assign GG_0 = E_in ^ F_in ^ G_in;
assign GG_1 = (E_in & F_in) | (~E_in & G_in);
assign GG = (index_j_in<16)? GG_0 : GG_1;
assign TT2 = GG + H_in + SS1 + Wj_in;

//P0(TT2) = (TT2) ^ (TT2<<<9) ^ (TT2<<<17)
assign P0 = TT2 ^ {TT2[22:0],TT2[31:23]} ^ {TT2[14:0],TT2[31:15]};

assign D_out = C_in;
assign C_out = {B_in[22:0],B_in[31:23]};
assign B_out = A_in;
assign A_out = TT1;
assign H_out = G_in;
assign G_out = {F_in[12:0],F_in[31:13]};
assign F_out = E_in;
assign E_out = P0;

cyclic_shifter shift0(
    .data_in(Tj),
    .shift_num(index_j_in),
    .shift_result_out(Tj_shift)
);
endmodule //Compress_Func